/*
 * Precompilador.h
 */

#ifndef PRECOMPILADOR_H_
#define PRECOMPILADOR_H_

#include <iostream>
#include <sstream>
#include <string>
#include "HttpParser.h"
#include "Parser.h"
#include "PilaCondicional.h"
#include "TablaDefiniciones.h"
#include "TiposComunes.h"

#define SEP_NOMBRE_ARCHIVO "\""
#define LONG_SEP_NOMBRE_ARCHIVO std::string(SEP_NOMBRE_ARCHIVO).size()
#define MAX_NIVEL_RECURSIVIDAD 100

class Precompilador {
private:
	std::string directorioArchivos;
	HttpParser* httpParser;
	PilaCondicional pilaIfs;
	TablaDefiniciones tablaDef;

	// Permite cortar recursividad de precompilación.
	int nivelRecursividad;

	/** Identifica y procesa una directiva a gcc según corresponda.
	 * @param parser Puntero al parser asociado al archivo en proceso.
	 * @param directivLeida Cadena con la directiva a procesar.
	 * @param valorDirectiv Cadena con los argumentos de la directiva.
	 * @return Verdadero si pudo procesarla.
	 */
	bool procesarDirectivas(const Parser* parser,
			const std::string &directivLeida,
			const std::string &valorDirectiv);

	/** Recibe argumento de directivas ifdef e ifndef y lo procesa.
	 * @param valorDirectiva Argumento de directiva.
	 * @param verdad Verdadero para procesar ifdef, falso caso contrario.
	 * @return Verdadero si pudo procesar la directiva.
	 */
	bool procDirectivCondicion(const std::string &valorDirectiva, bool verdad);
public:
	/** Crea una instancia asociada a un parser Http con archivos recibidos.
	 * @param hParser Referencia a un httpParser con datos recibidos.
	 */
	Precompilador(HttpParser &hParser);

	/** Crea una instancia asociada a un directorio con archivos a precompilar.
	 * @param hParser Referencia a un httpParser con datos recibidos.
	 */
	Precompilador(const std::string &directArch);

	virtual ~Precompilador() {}

	/** Precompila un archivo con sintaxis gcc. La entrada de archivos es del
	 * directorio o del parserHttp según el modo de instanciación de la clase.
	 * @param nombArch Nombre del archivo a precompilar.
	 * @return Verdadero si pudo precompilarlo.
	 */
	bool precompilarArchivo(const std::string &nombArch);
};

#endif /* PRECOMPILADOR_H_ */
